package com.lin.java.tool.send.email;

import cn.hutool.core.lang.Validator;
import com.lin.java.tool.send.SendStrategy;
import com.lin.java.tool.send.enums.EmailTemplateEnum;
import com.lin.java.tool.send.enums.SendEnum;
import com.lin.java.tool.send.ex.CustomSendException;
import com.lin.java.tool.send.factory.EmailFactory;
import com.lin.java.tool.send.model.dto.EmailDTO;
import com.lin.java.tool.send.model.EmailTemplate;

import java.util.*;

/**
 * @author: linjiang
 * @date: 2025/1/16
 * 邮箱策略
 */
public abstract class EmailStrategy<T extends EmailDTO> implements SendStrategy<T> {
    /**
     * 邮箱模板缓存
     */
    protected final Map<String, EmailTemplate> emailTemplateCache = new HashMap<>(16);
    /**
     * 邮件工厂
     */
    protected EmailFactory factory;
    /**
     * 调用外部配置的模板
     */
    protected InitializeEmailTemplate otherTemplate;

    public EmailStrategy(EmailFactory factory, InitializeEmailTemplate initializeEmailTemplate) {
        this.otherTemplate = initializeEmailTemplate;
        this.factory = factory;
        initEmailTemplate();
    }

    /**
     * 初始化邮箱模板
     */
    private void initEmailTemplate() {
        EmailTemplateEnum[] values = EmailTemplateEnum.values();
        for (EmailTemplateEnum template : values) {
            EmailTemplate dto = new EmailTemplate();
            dto.setSubject(template.getSubject());
            dto.setContent(template.getTemplate());
            dto.setHtml(template.getHtml());
            emailTemplateCache.put(template.name(), dto);
        }
    }

    @Override
    public Boolean send(T send) {
        preCheck(send);

        // 校验缓存是否已经包含了模板tag
        if (!emailTemplateCache.containsKey(send.getTag())) {
            Map<String, EmailTemplate> otherTemplateCache = new HashMap<>(16);
            Optional.ofNullable(otherTemplate).ifPresent((service -> service.load(otherTemplateCache)));
            emailTemplateCache.putAll(otherTemplateCache);
        }

        // 获取模板
        EmailTemplate template = emailTemplateCache.get(send.getTag());
        if (template == null) {
            throw new CustomSendException(SendEnum.SEND_FAIl.getCode(), "邮件模板不存在！");
        }
        this.sendEmail(template, send);
        return Boolean.TRUE;
    }

    /**
     * 发送邮件
     *
     * @param template
     * @param send
     */
    protected abstract void sendEmail(EmailTemplate template, T send);

    /**
     * 参数校验
     *
     * @param email
     */
    private void preCheck(EmailDTO email) {
        List<String> emails = email.getEmails();
        if (Objects.isNull(emails)) {
            throw new CustomSendException(SendEnum.SEND_FAIl.getCode(), "接收人邮箱不能为空！");
        }
        // 1. 校验邮件规范
        StringJoiner joiner = new StringJoiner(",");
        boolean match = emails.stream().allMatch(var -> {
            boolean bool = Validator.isEmail(var);
            if (!bool) {
                joiner.add(var);
            }
            return bool;
        });
        if (!match) {
            throw new CustomSendException(SendEnum.SEND_FAIl.getCode(), "存在不规范的邮箱【" + joiner + "】");
        }
    }


}
